package org.zxp.thread.threadpool;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * @program: zxp-thread-test
 * @description: ${description}
 * @author: X-Pacific zhang
 * @create: 2019-05-30 11:41
 **/
public class ExcutorsTest {
    /**
     * 随着任务量增加线程增加，执行完成后60s没任务线程自动关闭(核心线程数为0)
     *SynchronousQueue
     * 风险：线程数可能无限添加
     */
    @Test
    public void testCachedThreadPool() throws InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        List<Callable<String>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            final int j = i;
            list.add(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {}System.out.println("任务"+(j+1)+"，线程名称："+Thread.currentThread().getName());return j+"";});
        }
        executor.invokeAll(list);
        //到了60秒worker个数为0
        try {
            Thread.sleep(10000000000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 同时只能执行一个线程，按顺序FIFO的执行
     * LinkedBlockingQueue
     * 风险：任务队列可能无限添加
     */
    @Test
    public void testSingleThreadExecutor() throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
//        for (int i = 0; i < 1000; i++) {
//            final int j = i;
//            executor.submit(() -> {try {Thread.sleep(100);} catch (InterruptedException e) {}System.out.println("任务"+(j+1)+"，线程名称："+Thread.currentThread().getName());});
//        }

        List<Callable<String>> list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            final int j = i;
            list.add(() -> {try {Thread.sleep(100);} catch (InterruptedException e) {}System.out.println("任务"+(j+1)+"，线程名称："+Thread.currentThread().getName());return j+"";});
        }
        executor.invokeAll(list);
        try {Thread.sleep(10000000L);} catch (InterruptedException e) {}
    }

    /**
     * 同时只能执行N个线程
     * LinkedBlockingQueue
     * 风险：任务队列可能无限添加
     * @throws InterruptedException
     */
    @Test
    public void testFixedThreadPool() throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        List<Callable<String>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            final int j = i;
            list.add(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {}System.out.println("任务"+(j+1)+"，线程名称："+Thread.currentThread().getName());return j+"";});
        }
        executor.invokeAll(list);
        try {Thread.sleep(10000000L);} catch (InterruptedException e) {}
    }

    /**
     *可以设定延迟执行（可能带返回值）或周期执行（不能带返回值）
     * DelayedWorkQueue
     *风险：线程数可能无限添加
     * @throws InterruptedException
     */
    @Test
    public void testScheduledThreadPool() throws InterruptedException, ExecutionException {
        //入参是核心线程数
        ExecutorService executor = Executors.newScheduledThreadPool(3);
        //入参分别是Runnable，多少时间后执行，每多少时间执行一次，时间单位
//        ((ScheduledExecutorService) executor).scheduleAtFixedRate(() -> {System.out.println(new Date());}, 5,3, TimeUnit.SECONDS);
        Future<String> future = ((ScheduledExecutorService) executor).schedule(() -> {return new Date()+"";}, 5, TimeUnit.SECONDS);
        System.out.println(future.get());//在这里挂起
        try {Thread.sleep(10000000L);} catch (InterruptedException e) {}
        //newSingleThreadScheduledExecutor就是单个线程的
    }
}
